{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C:\\Users\\IDEA\\Documents\\experimentos\\pits\\lucia2022\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'C:\\\\Users\\\\IDEA\\\\Documents\\\\experimentos\\\\pits\\\\lucia2022'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Modify working directory accordingly. This step is not necessary because the directory will be specified below. A portion of the code below is adapted from Deep Learning with Python, by Francois Chollet, 2017, Manning Publications.\n",
    "\n",
    "%cd \"C:\\\\Users\\\\IDEA\\\\Documents\\\\experimentos\\\\pits\\\\lucia2022\"\n",
    "%pwd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'2.4.3'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import keras\n",
    "keras.__version__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "#MODULE 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os, shutil\n",
    "original_dir= \"C:\\\\Users\\\\IDEA\\\\Documents\\\\experimentos\\\\pits\\\\lucia2022\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# The directory where we will\n",
    "# store our smaller dataset\n",
    "base_dir = \"C:\\\\Users\\\\IDEA\\\\Documents\\\\experimentos\\\\pits\\\\lucia2022\\\\conv\"\n",
    "os.mkdir(base_dir)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Directories for our training,validation/test splits\n",
    "train_dir = os.path.join(base_dir, 'train')\n",
    "os.mkdir(train_dir)\n",
    "validation_dir = os.path.join(base_dir, 'validation')\n",
    "os.mkdir(validation_dir)\n",
    "\n",
    "\n",
    "# Directory with our training lion pictures\n",
    "train_lions_dir = os.path.join(train_dir, 'LP')\n",
    "os.mkdir(train_lions_dir)\n",
    "\n",
    "# Directory with our training hyena pictures\n",
    "train_hyenas_dir = os.path.join(train_dir, 'HP1')\n",
    "os.mkdir(train_hyenas_dir)\n",
    "\n",
    "# Directory with our validation lion pictures\n",
    "validation_lions_dir = os.path.join(validation_dir, 'LP')\n",
    "os.mkdir(validation_lions_dir)\n",
    "\n",
    "# Directory with our validation hyena pictures\n",
    "validation_hyenas_dir = os.path.join(validation_dir, 'HP1')\n",
    "os.mkdir(validation_hyenas_dir)\n",
    "\n",
    "\n",
    "\n",
    "# Copy first 20 CM images to train_lions_dir\n",
    "fnames = ['LP.{}.bmp'.format(i) for i in range(25)]\n",
    "for fname in fnames:\n",
    "    src = os.path.join(original_dir, fname)\n",
    "    dst = os.path.join(train_lions_dir, fname)\n",
    "    shutil.copyfile(src, dst)\n",
    "\n",
    "# Copy next 10 CM images to validation_lions_dir\n",
    "fnames = ['LP.{}.bmp'.format(i) for i in range(25, 34)]\n",
    "for fname in fnames:\n",
    "    src = os.path.join(original_dir, fname)\n",
    "    dst = os.path.join(validation_lions_dir, fname)\n",
    "    shutil.copyfile(src, dst)\n",
    "    \n",
    "\n",
    "    \n",
    "# Copy first 20 TM images to train_hyenas_dir\n",
    "fnames = ['HP1.{}.bmp'.format(i) for i in range(30)]\n",
    "for fname in fnames:\n",
    "    src = os.path.join(original_dir, fname)\n",
    "    dst = os.path.join(train_hyenas_dir, fname)\n",
    "    shutil.copyfile(src, dst)\n",
    "    \n",
    "# Copy next 10 TM images to validation_hyenas_dir\n",
    "fnames = ['HP1.{}.bmp'.format(i) for i in range(30, 44)]\n",
    "for fname in fnames:\n",
    "    src = os.path.join(original_dir, fname)\n",
    "    dst = os.path.join(validation_hyenas_dir, fname)\n",
    "    shutil.copyfile(src, dst)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#Select pre-processing standardization according to transfer model\n",
    "\n",
    "from keras.applications.densenet import preprocess_input#DENSENET201\n",
    "from keras.applications.resnet50 import preprocess_input#RESNET50\n",
    "from keras.applications.inception_resnet_v2 import preprocess_input #InceptionResNetV2 \n",
    "from keras.applications.nasnet import preprocess_input #NASNetLarge\n",
    "from keras.applications.inception_v3 import preprocess_input #InceptionV3\n",
    "from keras.applications.vgg19 import preprocess_input #VGG19\n",
    "from keras.applications.vgg16 import preprocess_input #VGG16\n",
    "from keras.applications.imagenet_utils import decode_predictions, preprocess_input#for efficient Net"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 55 images belonging to 2 classes.\n",
      "Found 23 images belonging to 2 classes.\n"
     ]
    }
   ],
   "source": [
    "#No AUGMENTATION\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from keras.applications.resnet50 import preprocess_input #AQUÍ COPIAR DE ARRIBA SEGÚN MODELO\n",
    "\n",
    "# All images will be rescaled by 1./255\n",
    "#train_datagen = ImageDataGenerator(rescale=1./255)\n",
    "#test_datagen = ImageDataGenerator(rescale=1./255)\n",
    "\n",
    "#for DENSENET\n",
    "train_datagen = ImageDataGenerator(\n",
    "    preprocessing_function= \\\n",
    "    keras.applications.densenet.preprocess_input)#OJO!!!\n",
    "test_datagen = ImageDataGenerator(\n",
    "    preprocessing_function= \\\n",
    "    keras.applications.resnet50.preprocess_input)#OJO!!!\n",
    "\n",
    "\n",
    "train_generator = train_datagen.flow_from_directory(\n",
    "        # This is the target directory\n",
    "        train_dir,\n",
    "        # All images will be resized to 40x160\n",
    "        target_size=(150, 200),\n",
    "        batch_size=20,\n",
    "        # Since we use binary_crossentropy loss, we need binary labels\n",
    "        class_mode='binary')\n",
    "\n",
    "validation_generator = test_datagen.flow_from_directory(\n",
    "        validation_dir,\n",
    "        target_size=(150, 200),\n",
    "        batch_size=10,\n",
    "        class_mode='binary', \n",
    "        shuffle=False)#or True for more randomization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 55 images belonging to 2 classes.\n",
      "Found 23 images belonging to 2 classes.\n"
     ]
    }
   ],
   "source": [
    "#WITH AUGMENTATION\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from keras.applications.resnet50 import preprocess_input\n",
    "#from keras.applications.imagenet_utils import decode_predictions, preprocess_input#for efficient Net#modify according to model selected\n",
    "\n",
    "\n",
    "#Let's train our network using data augmentation:\n",
    "train_datagen = ImageDataGenerator(\n",
    "    rotation_range=40,\n",
    "    width_shift_range=0.2,\n",
    "    height_shift_range=0.2,\n",
    "    shear_range=0.2,\n",
    "    zoom_range=0.2,\n",
    "    horizontal_flip=True,\n",
    "    preprocessing_function= \\\n",
    "    keras.applications.resnet50.preprocess_input)#OJO!!!!\n",
    "\n",
    "# Note that the validation data should not be augmented!\n",
    "test_datagen = ImageDataGenerator(preprocessing_function= \\\n",
    "    keras.applications.resnet50.preprocess_input)#OJO!!!\n",
    "\n",
    "train_generator = train_datagen.flow_from_directory(\n",
    "        # This is the target directory\n",
    "        train_dir,\n",
    "        # All images will be resized to 150x150\n",
    "        target_size=(150, 200),\n",
    "        batch_size=20,\n",
    "        # Since we use binary_crossentropy loss, we need binary labels\n",
    "        class_mode='binary')#put \"categorical\" si son más de 2 categorías\n",
    "\n",
    "validation_generator = test_datagen.flow_from_directory(\n",
    "        validation_dir,\n",
    "        target_size=(150, 200),\n",
    "        batch_size=10,\n",
    "        class_mode='binary',#use \"categorical\" for non-binomials\n",
    "        shuffle=False)#or True for more randomization "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#MODULE 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#MODELS: select one and move to the next module"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "# transfer learning fpr VGG19\n",
    "import sys\n",
    "from matplotlib import pyplot\n",
    "from keras.applications.vgg19 import VGG19\n",
    "from keras.models import Model\n",
    "from keras.layers import Dense\n",
    "from keras.layers import Flatten\n",
    "from keras.optimizers import SGD\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "# define cnn model\n",
    "def define_model():\n",
    "\t# load model\n",
    "\tmodel = VGG19(include_top=False, input_shape=(150, 200, 3))\n",
    "\t# mark loaded layers as not trainable\n",
    "\tfor layer in model.layers:\n",
    "\t\tlayer.trainable = False\n",
    "\t# add new classifier layers\n",
    "\tflat1 = Flatten()(model.layers[-1].output)\n",
    "\tclass1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)\n",
    "\toutput = Dense(1, activation='sigmoid')(class1)\n",
    "\t# define new model\n",
    "\tmodel = Model(inputs=model.inputs, outputs=output)\n",
    "\t# compile model\n",
    "\topt = SGD(lr=0.001, momentum=0.9)\n",
    "\tmodel.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])\n",
    "\treturn model\n",
    "\n",
    "# define model\n",
    "model = define_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "# transfer learning fpr VGG19 with Dropout\n",
    "import sys\n",
    "from matplotlib import pyplot\n",
    "from keras.applications.vgg19 import VGG19\n",
    "from keras.models import Model\n",
    "from keras.layers import Dense\n",
    "from keras.layers import Flatten\n",
    "from keras.optimizers import SGD\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "# define cnn model\n",
    "def define_model():\n",
    "\t# load model\n",
    "\tmodel = VGG19(include_top=False, input_shape=(150, 200, 3))\n",
    "\t# mark loaded layers as not trainable\n",
    "\tfor layer in model.layers:\n",
    "\t\tlayer.trainable = False\n",
    "\t# add new classifier layers\n",
    "\tflat1 = Flatten()(model.layers[-1].output)\n",
    "\tclass1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)\n",
    "\tdrop=Dropout(0.3)(class1)\n",
    "\toutput = Dense(1, activation='sigmoid')(drop)\n",
    "\t# define new model\n",
    "\tmodel = Model(inputs=model.inputs, outputs=output)\n",
    "\t# compile model\n",
    "\topt = SGD(lr=0.001, momentum=0.9)\n",
    "\tmodel.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])\n",
    "\treturn model\n",
    "\n",
    "# define model\n",
    "model = define_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# for transfer learning RESNET50\n",
    "import sys\n",
    "from matplotlib import pyplot\n",
    "from keras.applications.resnet50 import ResNet50\n",
    "from keras.models import Model\n",
    "from keras.layers import Dense\n",
    "from keras.layers import Flatten\n",
    "from keras.optimizers import SGD\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "# define cnn model\n",
    "def define_model():\n",
    "\t# load model\n",
    "\tmodel = ResNet50(include_top=False, input_shape=(150, 200, 3))\n",
    "\t# mark loaded layers as not trainable\n",
    "\tfor layer in model.layers:\n",
    "\t\tlayer.trainable = False\n",
    "\t# add new classifier layers\n",
    "\tflat1 = Flatten()(model.layers[-1].output)\n",
    "\tclass1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)\n",
    "\toutput = Dense(1, activation='sigmoid')(class1)\n",
    "\t# define new model\n",
    "\tmodel = Model(inputs=model.inputs, outputs=output)\n",
    "\t# compile model\n",
    "\topt = SGD(lr=0.001, momentum=0.9)\n",
    "\tmodel.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])\n",
    "\treturn model\n",
    "\n",
    "# define model\n",
    "model = define_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "# for transfer learning RESNET50 with Dropout\n",
    "import sys\n",
    "from matplotlib import pyplot\n",
    "from keras.applications.resnet50 import ResNet50\n",
    "from keras.models import Model\n",
    "from keras.layers import Dense\n",
    "from keras.layers import Flatten\n",
    "from keras.layers import Dropout\n",
    "from keras.optimizers import SGD\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "# define cnn model\n",
    "def define_model():\n",
    "\t# load model\n",
    "\tmodel = ResNet50(include_top=False, input_shape=(150, 200, 3))\n",
    "\t# mark loaded layers as not trainable\n",
    "\tfor layer in model.layers:\n",
    "\t\tlayer.trainable = False\n",
    "\t# add new classifier layers\n",
    "\tflat1 = Flatten()(model.layers[-1].output)\n",
    "\tclass1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)\n",
    "\tdrop=Dropout(0.5)(class1)\n",
    "\toutput = Dense(1, activation='sigmoid')(drop)\n",
    "\t# define new model\n",
    "\tmodel = Model(inputs=model.inputs, outputs=output)\n",
    "\t# compile model\n",
    "\topt = SGD(lr=0.001, momentum=0.9)\n",
    "\tmodel.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])\n",
    "\treturn model\n",
    "\n",
    "# define model\n",
    "model = define_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#MODULE 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#run selected model next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/100\n",
      "3/3 [==============================] - 3s 846ms/step - loss: 2.0370 - accuracy: 0.6491 - val_loss: 0.5834 - val_accuracy: 0.8261\n",
      "Epoch 2/100\n",
      "3/3 [==============================] - 2s 614ms/step - loss: 2.6207 - accuracy: 0.7534 - val_loss: 0.5944 - val_accuracy: 0.8696\n",
      "Epoch 3/100\n",
      "3/3 [==============================] - 2s 591ms/step - loss: 1.6282 - accuracy: 0.8028 - val_loss: 0.1869 - val_accuracy: 0.9565\n",
      "Epoch 4/100\n",
      "3/3 [==============================] - 2s 584ms/step - loss: 0.2726 - accuracy: 0.9531 - val_loss: 0.0636 - val_accuracy: 0.9565\n",
      "Epoch 5/100\n",
      "3/3 [==============================] - 2s 586ms/step - loss: 0.1002 - accuracy: 0.9675 - val_loss: 0.0923 - val_accuracy: 0.9565\n",
      "Epoch 6/100\n",
      "3/3 [==============================] - 2s 614ms/step - loss: 0.0509 - accuracy: 0.9838 - val_loss: 0.1978 - val_accuracy: 0.9565\n",
      "Epoch 7/100\n",
      "3/3 [==============================] - 2s 637ms/step - loss: 0.6044 - accuracy: 0.9675 - val_loss: 0.1494 - val_accuracy: 0.9565\n",
      "Epoch 8/100\n",
      "3/3 [==============================] - 2s 679ms/step - loss: 0.0994 - accuracy: 0.9838 - val_loss: 0.0357 - val_accuracy: 0.9565\n",
      "Epoch 9/100\n",
      "3/3 [==============================] - 2s 608ms/step - loss: 0.0303 - accuracy: 0.9747 - val_loss: 0.0171 - val_accuracy: 1.0000\n",
      "Epoch 10/100\n",
      "3/3 [==============================] - 2s 601ms/step - loss: 0.0752 - accuracy: 0.9909 - val_loss: 0.0191 - val_accuracy: 1.0000\n",
      "Epoch 11/100\n",
      "3/3 [==============================] - 2s 571ms/step - loss: 0.0278 - accuracy: 0.9722 - val_loss: 0.0503 - val_accuracy: 0.9565\n",
      "Epoch 12/100\n",
      "3/3 [==============================] - 2s 577ms/step - loss: 0.0126 - accuracy: 1.0000 - val_loss: 0.0871 - val_accuracy: 0.9565\n",
      "Epoch 13/100\n",
      "3/3 [==============================] - 2s 596ms/step - loss: 0.0188 - accuracy: 1.0000 - val_loss: 0.0887 - val_accuracy: 0.9565\n",
      "Epoch 14/100\n",
      "3/3 [==============================] - 2s 657ms/step - loss: 0.0030 - accuracy: 1.0000 - val_loss: 0.0841 - val_accuracy: 0.9130\n",
      "Epoch 15/100\n",
      "3/3 [==============================] - 2s 670ms/step - loss: 0.0123 - accuracy: 1.0000 - val_loss: 0.0640 - val_accuracy: 0.9565\n",
      "Epoch 16/100\n",
      "3/3 [==============================] - 2s 569ms/step - loss: 0.1296 - accuracy: 0.9713 - val_loss: 0.0247 - val_accuracy: 1.0000\n",
      "Epoch 17/100\n",
      "3/3 [==============================] - 2s 582ms/step - loss: 0.0926 - accuracy: 0.9818 - val_loss: 0.0187 - val_accuracy: 1.0000\n",
      "Epoch 18/100\n",
      "3/3 [==============================] - 2s 598ms/step - loss: 0.1172 - accuracy: 0.9693 - val_loss: 0.0335 - val_accuracy: 1.0000\n",
      "Epoch 19/100\n",
      "3/3 [==============================] - 2s 604ms/step - loss: 0.0160 - accuracy: 0.9909 - val_loss: 0.0583 - val_accuracy: 0.9565\n",
      "Epoch 20/100\n",
      "3/3 [==============================] - 2s 592ms/step - loss: 0.0332 - accuracy: 0.9713 - val_loss: 0.1196 - val_accuracy: 0.9130\n",
      "Epoch 21/100\n",
      "3/3 [==============================] - 2s 583ms/step - loss: 0.0838 - accuracy: 0.9747 - val_loss: 0.1350 - val_accuracy: 0.9130\n",
      "Epoch 22/100\n",
      "3/3 [==============================] - 2s 628ms/step - loss: 0.0027 - accuracy: 1.0000 - val_loss: 0.1444 - val_accuracy: 0.9130\n",
      "Epoch 23/100\n",
      "3/3 [==============================] - 2s 701ms/step - loss: 0.0025 - accuracy: 1.0000 - val_loss: 0.1539 - val_accuracy: 0.9130\n",
      "Epoch 24/100\n",
      "3/3 [==============================] - 2s 592ms/step - loss: 0.0142 - accuracy: 1.0000 - val_loss: 0.1437 - val_accuracy: 0.9130\n",
      "Epoch 25/100\n",
      "3/3 [==============================] - 2s 612ms/step - loss: 0.0218 - accuracy: 0.9747 - val_loss: 0.1584 - val_accuracy: 0.9130\n",
      "Epoch 26/100\n",
      "3/3 [==============================] - 2s 610ms/step - loss: 0.0034 - accuracy: 1.0000 - val_loss: 0.2029 - val_accuracy: 0.9130\n",
      "Epoch 27/100\n",
      "3/3 [==============================] - 2s 620ms/step - loss: 0.0063 - accuracy: 1.0000 - val_loss: 0.2463 - val_accuracy: 0.9130\n",
      "Epoch 28/100\n",
      "3/3 [==============================] - 2s 635ms/step - loss: 0.0032 - accuracy: 1.0000 - val_loss: 0.2613 - val_accuracy: 0.8696\n",
      "Epoch 29/100\n",
      "3/3 [==============================] - 2s 556ms/step - loss: 0.0050 - accuracy: 1.0000 - val_loss: 0.2755 - val_accuracy: 0.8696\n",
      "Epoch 30/100\n",
      "3/3 [==============================] - 2s 601ms/step - loss: 0.0703 - accuracy: 0.9722 - val_loss: 0.2076 - val_accuracy: 0.9130\n",
      "Epoch 31/100\n",
      "3/3 [==============================] - 2s 656ms/step - loss: 0.0123 - accuracy: 1.0000 - val_loss: 0.1227 - val_accuracy: 0.9130\n",
      "Epoch 32/100\n",
      "3/3 [==============================] - 2s 694ms/step - loss: 0.0014 - accuracy: 1.0000 - val_loss: 0.0691 - val_accuracy: 0.9565\n",
      "Epoch 33/100\n",
      "3/3 [==============================] - 2s 569ms/step - loss: 0.0066 - accuracy: 1.0000 - val_loss: 0.0474 - val_accuracy: 1.0000\n",
      "Epoch 34/100\n",
      "3/3 [==============================] - 2s 554ms/step - loss: 0.0048 - accuracy: 1.0000 - val_loss: 0.0395 - val_accuracy: 1.0000\n",
      "Epoch 35/100\n",
      "3/3 [==============================] - 2s 597ms/step - loss: 0.0064 - accuracy: 1.0000 - val_loss: 0.0408 - val_accuracy: 1.0000\n",
      "Epoch 36/100\n",
      "3/3 [==============================] - 2s 568ms/step - loss: 0.0947 - accuracy: 0.9713 - val_loss: 0.0861 - val_accuracy: 0.9565\n",
      "Epoch 37/100\n",
      "3/3 [==============================] - 2s 608ms/step - loss: 0.0095 - accuracy: 1.0000 - val_loss: 0.1453 - val_accuracy: 0.9130\n",
      "Epoch 38/100\n",
      "3/3 [==============================] - 2s 643ms/step - loss: 0.1246 - accuracy: 0.9671 - val_loss: 0.1322 - val_accuracy: 0.9130\n",
      "Epoch 39/100\n",
      "3/3 [==============================] - 2s 689ms/step - loss: 0.2847 - accuracy: 0.9747 - val_loss: 0.0634 - val_accuracy: 0.9565\n",
      "Epoch 40/100\n",
      "3/3 [==============================] - 2s 613ms/step - loss: 2.3459e-04 - accuracy: 1.0000 - val_loss: 0.0169 - val_accuracy: 1.0000\n",
      "Epoch 41/100\n",
      "3/3 [==============================] - 2s 667ms/step - loss: 0.1200 - accuracy: 0.9671 - val_loss: 0.0166 - val_accuracy: 1.0000\n",
      "Epoch 42/100\n",
      "3/3 [==============================] - 2s 652ms/step - loss: 0.2304 - accuracy: 0.9838 - val_loss: 0.0282 - val_accuracy: 1.0000\n",
      "Epoch 43/100\n",
      "3/3 [==============================] - 2s 618ms/step - loss: 0.0019 - accuracy: 1.0000 - val_loss: 0.0546 - val_accuracy: 0.9565\n",
      "Epoch 44/100\n",
      "3/3 [==============================] - 2s 606ms/step - loss: 2.3962e-04 - accuracy: 1.0000 - val_loss: 0.0865 - val_accuracy: 0.9565\n",
      "Epoch 45/100\n",
      "3/3 [==============================] - 2s 665ms/step - loss: 0.2152 - accuracy: 0.9584 - val_loss: 0.0514 - val_accuracy: 0.9565\n",
      "Epoch 46/100\n",
      "3/3 [==============================] - 2s 661ms/step - loss: 0.1317 - accuracy: 0.9671 - val_loss: 0.0109 - val_accuracy: 1.0000\n",
      "Epoch 47/100\n",
      "3/3 [==============================] - 2s 605ms/step - loss: 5.4695e-04 - accuracy: 1.0000 - val_loss: 0.0126 - val_accuracy: 1.0000\n",
      "Epoch 48/100\n",
      "3/3 [==============================] - 2s 638ms/step - loss: 0.0223 - accuracy: 0.9818 - val_loss: 0.0194 - val_accuracy: 1.0000\n",
      "Epoch 49/100\n",
      "3/3 [==============================] - 2s 623ms/step - loss: 0.0244 - accuracy: 0.9909 - val_loss: 0.0167 - val_accuracy: 1.0000\n",
      "Epoch 50/100\n",
      "3/3 [==============================] - 2s 605ms/step - loss: 0.1160 - accuracy: 0.9550 - val_loss: 0.0093 - val_accuracy: 1.0000\n",
      "Epoch 51/100\n",
      "3/3 [==============================] - 2s 651ms/step - loss: 0.0011 - accuracy: 1.0000 - val_loss: 0.0117 - val_accuracy: 1.0000\n",
      "Epoch 52/100\n",
      "3/3 [==============================] - 2s 605ms/step - loss: 0.0042 - accuracy: 1.0000 - val_loss: 0.0180 - val_accuracy: 1.0000\n",
      "Epoch 53/100\n",
      "3/3 [==============================] - 2s 603ms/step - loss: 0.0772 - accuracy: 0.9847 - val_loss: 0.0190 - val_accuracy: 1.0000\n",
      "Epoch 54/100\n",
      "3/3 [==============================] - 2s 670ms/step - loss: 0.0078 - accuracy: 0.9909 - val_loss: 0.0175 - val_accuracy: 1.0000\n",
      "Epoch 55/100\n",
      "3/3 [==============================] - 2s 659ms/step - loss: 4.4755e-06 - accuracy: 1.0000 - val_loss: 0.0150 - val_accuracy: 1.0000\n",
      "Epoch 56/100\n",
      "3/3 [==============================] - 2s 597ms/step - loss: 2.8119e-04 - accuracy: 1.0000 - val_loss: 0.0135 - val_accuracy: 1.0000\n",
      "Epoch 57/100\n",
      "3/3 [==============================] - 2s 591ms/step - loss: 0.0204 - accuracy: 0.9847 - val_loss: 0.0150 - val_accuracy: 1.0000\n",
      "Epoch 58/100\n",
      "3/3 [==============================] - 2s 589ms/step - loss: 2.1363e-04 - accuracy: 1.0000 - val_loss: 0.0174 - val_accuracy: 1.0000\n",
      "Epoch 59/100\n",
      "3/3 [==============================] - 2s 695ms/step - loss: 0.0131 - accuracy: 1.0000 - val_loss: 0.0225 - val_accuracy: 1.0000\n",
      "Epoch 60/100\n",
      "3/3 [==============================] - 2s 659ms/step - loss: 0.0522 - accuracy: 0.9671 - val_loss: 0.0430 - val_accuracy: 1.0000\n",
      "Epoch 61/100\n",
      "3/3 [==============================] - 2s 574ms/step - loss: 0.0075 - accuracy: 1.0000 - val_loss: 0.0612 - val_accuracy: 0.9565\n",
      "Epoch 62/100\n",
      "3/3 [==============================] - 2s 684ms/step - loss: 0.0336 - accuracy: 0.9909 - val_loss: 0.0676 - val_accuracy: 0.9565\n",
      "Epoch 63/100\n",
      "3/3 [==============================] - 2s 616ms/step - loss: 1.0125e-04 - accuracy: 1.0000 - val_loss: 0.0607 - val_accuracy: 0.9565\n",
      "Epoch 64/100\n",
      "3/3 [==============================] - 2s 688ms/step - loss: 0.0348 - accuracy: 0.9580 - val_loss: 0.0394 - val_accuracy: 1.0000\n",
      "Epoch 65/100\n",
      "3/3 [==============================] - 2s 613ms/step - loss: 0.0194 - accuracy: 1.0000 - val_loss: 0.0270 - val_accuracy: 1.0000\n",
      "Epoch 66/100\n",
      "3/3 [==============================] - 2s 622ms/step - loss: 1.5433e-04 - accuracy: 1.0000 - val_loss: 0.0204 - val_accuracy: 1.0000\n",
      "Epoch 67/100\n",
      "3/3 [==============================] - 2s 606ms/step - loss: 0.0238 - accuracy: 0.9909 - val_loss: 0.0186 - val_accuracy: 1.0000\n",
      "Epoch 68/100\n",
      "3/3 [==============================] - 2s 611ms/step - loss: 2.1159e-04 - accuracy: 1.0000 - val_loss: 0.0207 - val_accuracy: 1.0000\n",
      "Epoch 69/100\n",
      "3/3 [==============================] - 2s 696ms/step - loss: 0.0676 - accuracy: 0.9838 - val_loss: 0.0273 - val_accuracy: 1.0000\n",
      "Epoch 70/100\n",
      "3/3 [==============================] - 2s 613ms/step - loss: 1.6738e-05 - accuracy: 1.0000 - val_loss: 0.0366 - val_accuracy: 1.0000\n",
      "Epoch 71/100\n",
      "3/3 [==============================] - 2s 665ms/step - loss: 7.7467e-05 - accuracy: 1.0000 - val_loss: 0.0452 - val_accuracy: 1.0000\n",
      "Epoch 72/100\n",
      "3/3 [==============================] - 2s 603ms/step - loss: 0.0052 - accuracy: 1.0000 - val_loss: 0.0490 - val_accuracy: 1.0000\n",
      "Epoch 73/100\n",
      "3/3 [==============================] - 2s 682ms/step - loss: 7.2582e-04 - accuracy: 1.0000 - val_loss: 0.0457 - val_accuracy: 1.0000\n",
      "Epoch 74/100\n",
      "3/3 [==============================] - 2s 705ms/step - loss: 0.0122 - accuracy: 0.9909 - val_loss: 0.0376 - val_accuracy: 1.0000\n",
      "Epoch 75/100\n",
      "3/3 [==============================] - 2s 690ms/step - loss: 3.3789e-04 - accuracy: 1.0000 - val_loss: 0.0261 - val_accuracy: 1.0000\n",
      "Epoch 76/100\n",
      "3/3 [==============================] - 2s 623ms/step - loss: 3.6817e-04 - accuracy: 1.0000 - val_loss: 0.0201 - val_accuracy: 1.0000\n",
      "Epoch 77/100\n",
      "3/3 [==============================] - 2s 680ms/step - loss: 0.0044 - accuracy: 1.0000 - val_loss: 0.0171 - val_accuracy: 1.0000\n",
      "Epoch 78/100\n",
      "3/3 [==============================] - 2s 682ms/step - loss: 3.5497e-04 - accuracy: 1.0000 - val_loss: 0.0154 - val_accuracy: 1.0000\n",
      "Epoch 79/100\n",
      "3/3 [==============================] - 2s 622ms/step - loss: 2.1762e-04 - accuracy: 1.0000 - val_loss: 0.0145 - val_accuracy: 1.0000\n",
      "Epoch 80/100\n",
      "3/3 [==============================] - 2s 580ms/step - loss: 5.1968e-04 - accuracy: 1.0000 - val_loss: 0.0138 - val_accuracy: 1.0000\n",
      "Epoch 81/100\n",
      "3/3 [==============================] - 2s 638ms/step - loss: 1.0314e-04 - accuracy: 1.0000 - val_loss: 0.0134 - val_accuracy: 1.0000\n",
      "Epoch 82/100\n",
      "3/3 [==============================] - 2s 570ms/step - loss: 0.0051 - accuracy: 1.0000 - val_loss: 0.0125 - val_accuracy: 1.0000\n",
      "Epoch 83/100\n",
      "3/3 [==============================] - 2s 593ms/step - loss: 0.0049 - accuracy: 1.0000 - val_loss: 0.0124 - val_accuracy: 1.0000\n",
      "Epoch 84/100\n",
      "3/3 [==============================] - 2s 626ms/step - loss: 9.5711e-04 - accuracy: 1.0000 - val_loss: 0.0126 - val_accuracy: 1.0000\n",
      "Epoch 85/100\n",
      "3/3 [==============================] - 2s 666ms/step - loss: 1.2281e-05 - accuracy: 1.0000 - val_loss: 0.0128 - val_accuracy: 1.0000\n",
      "Epoch 86/100\n",
      "3/3 [==============================] - 2s 547ms/step - loss: 3.5241e-04 - accuracy: 1.0000 - val_loss: 0.0130 - val_accuracy: 1.0000\n",
      "Epoch 87/100\n",
      "3/3 [==============================] - 2s 628ms/step - loss: 6.9085e-06 - accuracy: 1.0000 - val_loss: 0.0131 - val_accuracy: 1.0000\n",
      "Epoch 88/100\n",
      "3/3 [==============================] - 2s 603ms/step - loss: 1.9356e-05 - accuracy: 1.0000 - val_loss: 0.0132 - val_accuracy: 1.0000\n",
      "Epoch 89/100\n",
      "3/3 [==============================] - 2s 638ms/step - loss: 0.0025 - accuracy: 1.0000 - val_loss: 0.0137 - val_accuracy: 1.0000\n",
      "Epoch 90/100\n",
      "3/3 [==============================] - 2s 692ms/step - loss: 0.0239 - accuracy: 0.9838 - val_loss: 0.0173 - val_accuracy: 1.0000\n",
      "Epoch 91/100\n",
      "3/3 [==============================] - 2s 667ms/step - loss: 3.7952e-04 - accuracy: 1.0000 - val_loss: 0.0227 - val_accuracy: 1.0000\n",
      "Epoch 92/100\n",
      "3/3 [==============================] - 2s 643ms/step - loss: 5.4814e-05 - accuracy: 1.0000 - val_loss: 0.0279 - val_accuracy: 1.0000\n",
      "Epoch 93/100\n",
      "3/3 [==============================] - 2s 676ms/step - loss: 4.8712e-05 - accuracy: 1.0000 - val_loss: 0.0325 - val_accuracy: 1.0000\n",
      "Epoch 94/100\n",
      "3/3 [==============================] - 2s 628ms/step - loss: 2.6312e-04 - accuracy: 1.0000 - val_loss: 0.0361 - val_accuracy: 1.0000\n",
      "Epoch 95/100\n",
      "3/3 [==============================] - 2s 679ms/step - loss: 0.0011 - accuracy: 1.0000 - val_loss: 0.0382 - val_accuracy: 1.0000\n",
      "Epoch 96/100\n",
      "3/3 [==============================] - 2s 660ms/step - loss: 6.8255e-04 - accuracy: 1.0000 - val_loss: 0.0383 - val_accuracy: 1.0000\n",
      "Epoch 97/100\n",
      "3/3 [==============================] - 2s 615ms/step - loss: 1.3346e-04 - accuracy: 1.0000 - val_loss: 0.0380 - val_accuracy: 1.0000\n",
      "Epoch 98/100\n",
      "3/3 [==============================] - 2s 612ms/step - loss: 0.0020 - accuracy: 1.0000 - val_loss: 0.0364 - val_accuracy: 1.0000\n",
      "Epoch 99/100\n",
      "3/3 [==============================] - 2s 701ms/step - loss: 1.8784e-04 - accuracy: 1.0000 - val_loss: 0.0332 - val_accuracy: 1.0000\n",
      "Epoch 100/100\n",
      "3/3 [==============================] - 2s 635ms/step - loss: 6.4295e-06 - accuracy: 1.0000 - val_loss: 0.0308 - val_accuracy: 1.0000\n"
     ]
    }
   ],
   "source": [
    "history = model.fit_generator(\n",
    "      train_generator,\n",
    "      steps_per_epoch=3,\n",
    "      epochs=100,\n",
    "      validation_data=validation_generator,\n",
    "      validation_steps=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "#guardar modelo\n",
    "model_json=model.to_json()\n",
    "with open(\"vgg19_PITS_july22.json\", \"w\") as json_file:\n",
    "    json_file.write(model_json)\n",
    "#serializar los pesos\n",
    "model.save_weights(\"vgg19_PITS_july22.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#WHEN SHUFFLE= FALSE:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\IDEA\\Anaconda3\\envs\\gputest\\lib\\site-packages\\tensorflow\\python\\keras\\engine\\training.py:1905: UserWarning: `Model.predict_generator` is deprecated and will be removed in a future version. Please use `Model.predict`, which supports generators.\n",
      "  warnings.warn('`Model.predict_generator` is deprecated and '\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3/3 [==============================] - 1s 138ms/step\n"
     ]
    }
   ],
   "source": [
    "predictions=model.predict_generator(validation_generator, steps=len(validation_generator), verbose=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "val_preds = np.round(predictions)# from probabilities to 0 or 1\n",
    "val_trues = validation_generator.classes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[14  0]\n",
      " [ 0  9]]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "mat= confusion_matrix (val_trues,val_preds)\n",
    "print(mat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       1.00      1.00      1.00        14\n",
      "           1       1.00      1.00      1.00         9\n",
      "\n",
      "    accuracy                           1.00        23\n",
      "   macro avg       1.00      1.00      1.00        23\n",
      "weighted avg       1.00      1.00      1.00        23\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import classification_report\n",
    "print(classification_report(val_trues,val_preds))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "from sklearn.metrics import roc_auc_score\n",
    "roc_auc_score(val_trues,val_preds) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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gYgsEZHXfMuXi8gib501vBtjTCNL2nQjIkXAdOAkoBaYLyJzVXWpL00n4B5gtKquFJEeUbs5XlXXZS/bxhhjggpSox8GVKlqtaruAmYDZ0Wl+QHwlKquBFDVL7KbTWOMMekKEuj7AKt8r2u9ZX4HA51F5FUReUdEfuRbp8CL3vJJmWXXGBNmo0aN4oUXXqi37M4772TKlCkJt4ncjn3aaaexcePGBmluuOGGffezxzNnzhyWLt3XUMGvfvUrXnrppRRyX7iCBPpY05lE33zfEjgSOB04BbheRA721o1Q1aHAqcAlInJszIOITBKRShGpXLt2bbDcG2NCZfz48cyePbvestmzZ8cdWCzavHnz6NSpU1rHjg70v/71rznxxBPT2lehCXJ7ZS3Q1/e6BFgdI806Vf0K+EpEXgcGAx+p6mpwzTki8jSuKej16IOo6gxgBrgOU6kWxBiTfVdcAd7w8FkzZAjceWfsdWPHjuW6665j586dtG7dmuXLl7N69WpGjhzJxRdfzPz589m+fTtjx47lxhtvbLB9WVkZlZWVdOvWjWnTpvHQQw/Rt29funfvzpFHHgm4e+RnzJjBrl27OOigg3j44YdZsGABc+fO5bXXXuM3v/kNTz75JDfddBNnnHEGY8eO5eWXX+aqq65iz549fOtb3+Lee++ldevWlJWVcf755/PMM8+we/dunnjiCQYOHFgvT8uXL+e8887jq6++AuDuu+/eN/nJrbfeysMPP0yLFi049dRTueWWW6iqqmLy5MmsXbuWoqIinnjiCQ488MCMznmQGv18YICIlItIK2AcMDcqzV+Ab4tISxEpBo4CPhCRdiLSAUBE2gEnA4szyrExJrS6du3KsGHDeP755wFXmz/33HMREaZNm0ZlZSXvv/8+r732Gu+//37c/bzzzjvMnj2b9957j6eeeor58+fvW3f22Wczf/58Fi5cyKBBg/jTn/7E8OHDOfPMM7nttttYsGBBvcC6Y8cOJk6cyGOPPcaiRYvYs2cP995777713bp149133+Xiiy+O2TwUGc743Xff5bHHHts3C5Z/OOOFCxdy9dVXA24440suuYSFCxfy1ltv0atXr8xOKgFq9Kq6R0QuBV4AioCZqrpERCZ76+9T1Q9E5HngfWAv8EdVXSwi/YGnvZHcWgJ/VtXnM861MaZRxKt551Kk+eass85i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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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zJgxg127drGt/ovYhFpkoEP4h1KAizSd5jxX9bnPfY5WrVoBsGnTJs4991xee+01zIwdO3akXObUU0+lbdu2tG3blq5du/Lee+/Rs2fPveYZPnz4nmmDBw9m9erVdOjQgSOPPHLP9d2TJk2ipqYmY/2efPLJPRuVz3zmM2zYsIFNmzYxatQoLr/8cqqrq5kwYQI9e/Zk2LBhnHfeeezYsYMzzzyTwYMHN+alyUuL7HIRkabXnOeqDjzwwD33v/3tb3PCCSfw4osvcv/996e9Frtt27Z77rdq1Spl/3uqeRpyRXWqZcyMK6+8kttuu43t27czYsQIVq1axZgxY1iyZAk9evRg8uTJ3HnnnXmvr6EU6CKSUrHOVW3atIkePcL4f/PmzSt4+f369eNvf/sbq1evBuAXv/hF1mXGjBlDbXTyYPHixXTu3JlOnTrxxhtvMGDAAL75zW9SVVXFqlWrWLNmDV27duWCCy7gy1/+MitWrCh4G9JRoItIStXVUFMDlZVgFv7W1DR9V+c3vvENrrrqKkaNGsWuXbsKXn779u25+eabOeWUUxg9ejTdunXjoIMOyrjMzJkzWbZsGQMHDuTKK6/kjjvuAOD666/n2GOPZdCgQbRv355x48axePHiPSdJ77vvPi699NKCtyGdov2mqMZyEWl+r7zyCp/4xCeKXY2i27p1Kx06dMDdueSSS+jbty+XXXZZsau1j1TvV6PGchERiZuf/vSnDB48mP79+7Np0yYuvPDCYlepIFrsVS4iIg112WWX7Zd75I2lPXQRkZhQoIuIxIQCXUQkJhToIiIxoUAXkWYzduxYHnnkkb2mXX/99XzlK1/JuEziEufx48ezcePGfeaZOXMms2fPzrjuBQsW8PLLL+95/J3vfIdHH300j9qntj8Ns6tAF5FmM2nSJObPn7/XtPnz5+c0QBaEURIPPvjgBq27fqBfe+21nHTSSQ0qa3+lQBeRZjNx4kQeeOABPvroIwBWr17NO++8w+jRo7n44oupqqqif//+XHPNNSmX7927N++/H357ftasWRx99NGcdNJJe4bYhXCN+bBhwxg0aBBnn30227Zt46mnnmLhwoVcccUVDB48mDfeeIOpU6dy7733AvDYY48xZMgQBgwYwHnnnbenfr179+aaa65h6NChDBgwgFWrVmVsX7GH2dV16CIlavp0WLmy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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "#PLOT\n",
    "acc = history.history['accuracy']\n",
    "val_acc = history.history['val_accuracy']\n",
    "loss = history.history['loss']\n",
    "val_loss = history.history['val_loss']\n",
    "\n",
    "epochs = range(len(acc))\n",
    "\n",
    "plt.plot(epochs, acc, 'bo', label='Training acc')\n",
    "plt.plot(epochs, val_acc, 'b', label='Validation acc')\n",
    "plt.title('Training and validation accuracy')\n",
    "plt.legend()\n",
    "\n",
    "plt.figure()\n",
    "\n",
    "plt.plot(epochs, loss, 'bo', label='Training loss')\n",
    "plt.plot(epochs, val_loss, 'b', label='Validation loss')\n",
    "plt.title('Training and validation loss')\n",
    "plt.legend()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
